// Regression Forests.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

#include <string>
#include <iostream>
#include <fstream>

#include <cv.h>
#include <stdio.h>
#include <highgui.h>
#include <ml.h>
#include <map>

void print_result(float train_err, float test_err,
	const CvMat* _var_imp)
{
	printf( "train error    %f\n", train_err );
	printf( "test error    %f\n\n", test_err );

	if (_var_imp)
	{
		cv::Mat var_imp(_var_imp), sorted_idx;
		cv::sortIdx(var_imp, sorted_idx, CV_SORT_EVERY_ROW +
			CV_SORT_DESCENDING);

		printf( "variable importance:\n" );
		int i, n = (int)var_imp.total();
		int type = var_imp.type();
		CV_Assert(type == CV_32F || type == CV_64F);

		for( i = 0; i < n; i++)
		{
			int k = sorted_idx.at<int>(i);
			printf( "%d\t%f\n", k, type == CV_32F ?
				var_imp.at<float>(k) :
			var_imp.at<double>(k));
		}
	}
	printf("\n");
}

int main()
{
	const char* filename = "data.xml";
	int response_idx = 0;

	CvMLData data;
	data.read_csv( filename ); // read data
	data.set_response_idx( response_idx ); // set response index
	data.change_var_type( response_idx,
		CV_VAR_CATEGORICAL ); // set response type
	// split train and test data
	CvTrainTestSplit spl( 0.5f );
	data.set_train_test_split( &spl );
	data.set_miss_ch("?"); // set missing value

	CvRTrees rtrees;
	rtrees.train( &data, CvRTParams( 10, 2, 0, false,
		16, 0, true, 0, 100, 0, CV_TERMCRIT_ITER ));
	print_result( rtrees.calc_error( &data, CV_TRAIN_ERROR),
		rtrees.calc_error( &data, CV_TEST_ERROR ),
		rtrees.get_var_importance() );

	return 0;
}
